package cn.iune.erp.inventory;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.justep.baas.Utils;
import com.justep.baas.data.Row;
import com.justep.baas.data.RowState;
import com.justep.baas.data.Table;
import com.justep.baas.data.Transform;


@Transactional
@Service
public class StorageItemBatchServiceImpl implements IStorageItemBatchService {

	@Autowired
	private IStorageItemBatchDao dao;
	

	/*
	public JSONObject query(JSONObject data) throws Throwable {
		
		// 获取参数
		Object columns = data.getJSONObject("columns"); // 列定义
		Integer limit = data.getInteger("limit"); // 分页查询的行数
		Integer offset = data.getInteger("offset"); // 分页查询的行偏移
		String search = data.getString("search"); // 检索关键字
		String filter = data.getString("filter"); // 过滤条件
		String id = data.getString("id");

		
		// 存放SQL中的参数值
		List<Object> sqlParams = new ArrayList<Object>();
		// 存放SQL中的过滤条件
		List<String> filters = new ArrayList<String>();
		if (!CommonService.isEmptyString(search)) {
			// 增加过滤条件
			filters.add("itemNo LIKE ? OR storageNo LIKE ? OR storageName LIKE ?");
			// 检索关键字中如果没有%，则前后自动加%
			search = (search.indexOf("%") != -1) ? search : "%" + search + "%";
			// sqlParams的参数个数和顺序必须与过滤条件的?相匹配 
			for (int i = 0; i < 3; i++) {
				sqlParams.add(search);
			}
		}
		//处理过滤条件
		if (!CommonService.isEmptyString(filter)) {
			filters.add(filter);
		}
		//处理id
		if (!CommonService.isEmptyString(id)) {
			filters.add("fID='"+id+"'");
		}
	
		
		Table table = Transform.createTableByColumnsDefine((JSONObject) columns);
		
		if (offset != null && offset.equals(0)) {
			long rowCount = dao.getCount(filters, sqlParams);
			table.setTotal((int)rowCount);
		}

		String orderBy = "itemNo DESC";
				
		//获取数据
		List<Row> rows = listToRows(dao.query(filters,orderBy,sqlParams,offset,limit));
	    table.appendRows(rows);
		JSONObject json = Transform.tableToJson(table);
	
		return json;
	}


	public int save(JSONObject object) throws Throwable {
		// TODO Auto-generated method stub
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		List<StorageItemBatch> list = rowsToList(table.getRows());
		for(StorageItemBatch obj : list){
			if(RowState.NEW.equals(obj.getRowState())){
				dao.insert(obj);
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				dao.update(obj);
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				dao.delete(obj.getfID());
			}
		}
		return 0;
	}

	public List<Row> listToRows(List<StorageItemBatch> list){
		//添加行集
		List<Row> rows = new ArrayList<Row>();
		//循环行
	    for(StorageItemBatch o : list){
	    	rows.add(objectToRow(o));
	    }
	    return rows;
	}

	public List<StorageItemBatch> rowsToList(List<Row> rows){
		//添加行集
		List<StorageItemBatch> list = new ArrayList<StorageItemBatch>();
		//循环行
	    for(Row r : rows){
	    	list.add(rowToObject(r));
	    }
	    return list;
	}

	public Row objectToRow(StorageItemBatch obj){
    	
		Map<String, ColumnValue> values = new HashMap<String, ColumnValue>();
		//循环行中每一列
		ColumnValue value = new ColumnValue(obj.getfID());
		values.put("fID", value);

		value = new ColumnValue(obj.getFactoryNo());
 		values.put("factoryNo", value);
		value = new ColumnValue(obj.getFactoryName());
 		values.put("factoryName", value);

		value = new ColumnValue(obj.getStorageNo());
 		values.put("storageNo", value);
		value = new ColumnValue(obj.getStorageName());
 		values.put("storageName", value);
		value = new ColumnValue(obj.getFloorNo());
 		values.put("floorNo", value);
		
		value = new ColumnValue(obj.getItemNo());
 		values.put("itemNo", value);
		value = new ColumnValue(obj.getItemDescribe());
 		values.put("itemDescribe", value);
//		value = new ColumnValue(obj.getItemProperty());
// 		values.put("itemProperty", value);
		value = new ColumnValue(obj.getUnitCode());
 		values.put("unitCode", value);
		value = new ColumnValue(obj.getUnitName());
 		values.put("unitName", value);

 		value = new ColumnValue(obj.getMinQuantity());
 		values.put("minQuantity", value);
		value = new ColumnValue(obj.getMaxQuantity());
 		values.put("maxQuantity", value);
 		value = new ColumnValue(obj.getDateIn());
 		values.put("dateIn", value);
		value = new ColumnValue(obj.getDateOut());
 		values.put("dateOut", value);

 		value = new ColumnValue(obj.getQuantityL());
 		values.put("quantityL", value);
		value = new ColumnValue(obj.getPieceQuantityL());
 		values.put("pieceQuantityL", value);

		value = new ColumnValue(obj.getMaterialAmount());
 		values.put("materialAmount", value);
		value = new ColumnValue(obj.getHumanAmount());
 		values.put("workingAmount", value);
		value = new ColumnValue(obj.getManufactAmount());
 		values.put("manufactAmount", value);
		value = new ColumnValue(obj.getProcessAmount());
 		values.put("processAmount", value);
		value = new ColumnValue(obj.getCostingAmount());
 		values.put("costingAmount", value);
 		
		value = new ColumnValue(obj.getMaterialAmountPer());
 		values.put("materialAmountPer", value);
		value = new ColumnValue(obj.getHumanAmountPer());
 		values.put("workingAmountPer", value);
		value = new ColumnValue(obj.getManufactAmountPer());
 		values.put("manufactAmountPer", value);
		value = new ColumnValue(obj.getProcessAmountPer());
 		values.put("processAmountPer", value);
		value = new ColumnValue(obj.getCostingAmountPer());
 		values.put("costingAmountPer", value);

		value = new ColumnValue(obj.getUserId());
 		values.put("userId", value);
		value = new ColumnValue(obj.getEnterpriseNo());
 		values.put("enterpriseNo", value);
		value = new ColumnValue(obj.getEnterpriseName());
 		values.put("enterpriseName", value);

		value = new ColumnValue(obj.getVersion());
 		values.put("version", value);
		
		Row row = new Row(values,RowState.NONE);
		return row;
	}
	
	public StorageItemBatch rowToObject(Row row){
		StorageItemBatch obj = new StorageItemBatch();
		obj.setfID(row.getString("fID"));
	    
		obj.setFactoryNo(row.getString("factoryNo"));
		obj.setFactoryName(row.getString("factoryName"));

		obj.setStorageNo(row.getString("storageNo"));
		obj.setStorageName(row.getString("storageName"));
		obj.setFloorNo(row.getString("floorNo"));

		obj.setItemNo(row.getString("itemNo"));
		obj.setItemDescribe(row.getString("itemDescribe"));
//		obj.setItemProperty(row.getString("itemProperty"));
		obj.setUnitCode(row.getString("unitCode"));
		obj.setUnitName(row.getString("unitName"));

		obj.setMinQuantity(row.getDecimal("minQuantity"));
		obj.setMaxQuantity(row.getDecimal("maxQuantity"));
		obj.setDateIn(row.getDate("dateIn"));
		obj.setDateOut(row.getDate("dateOut"));
		
		obj.setQuantityL(row.getDecimal("quantityL"));
		obj.setPieceQuantityL(row.getDecimal("pieceQuantityL"));
		
		obj.setMaterialAmount(row.getDecimal("materialAmount"));
		obj.setHumanAmount(row.getDecimal("workingAmount"));
		obj.setManufactAmount(row.getDecimal("manufactAmount"));
		obj.setProcessAmount(row.getDecimal("processAmount"));
		obj.setCostingAmount(row.getDecimal("costingAmount"));
		
		obj.setMaterialAmountPer(row.getDecimal("materialAmountPer"));
		obj.setHumanAmountPer(row.getDecimal("workingAmountPer"));
		obj.setManufactAmountPer(row.getDecimal("manufactAmountPer"));
		obj.setProcessAmountPer(row.getDecimal("processAmountPer"));
		obj.setCostingAmountPer(row.getDecimal("costingAmountPer"));
		
		obj.setUserId(row.getString("userId"));

		obj.setEnterpriseNo(row.getString("enterpriseNo"));
		obj.setEnterpriseName(row.getString("enterpriseName"));
		
		obj.setVersion(row.getInteger("version"));
		
		obj.setRowState(row.getState());


		return obj;
	}
	*/
	
	@Transactional
	@Override
	public void insert(StorageItemBatch obj) {
		// TODO Auto-generated method stub
		dao.insert(obj);
	}
	
	@Transactional
	@Override
	public void delete(String fID) {
		// TODO Auto-generated method stub
		dao.delete(fID);
	}
	
	@Transactional
	@Override
	public void update(StorageItemBatch obj) {
		// TODO Auto-generated method stub
		dao.update(obj);
	}
	
	@Override
	public List<StorageItemBatch> getAll() {
		// TODO Auto-generated method stub
		return dao.getAll();
	}
	
	@Override
	public StorageItemBatch getByID(String fID) {
		// TODO Auto-generated method stub
		return dao.getByID(fID);
	}
	
	
	@Transactional
	@Override
	public JSONObject save(JSONObject object) throws ParseException  {
		// JSON转换Table
		Table table = Transform.jsonToTable(object);
		
		JSONObject data = new JSONObject();
		data.put("concept", table.getTableName());
		JSONArray rows = new JSONArray();
		List<String> idsNew = new ArrayList<String>();
		List<String> idsDel = new ArrayList<String>();
		
		List<Row> list = table.getRows();
		for(Row row : list){
			JSONObject javaObject= Transform.rowToJavaObject(table, row);
			StorageItemBatch obj = JSON.toJavaObject(javaObject, StorageItemBatch.class);
			if(RowState.NEW.equals(obj.getRowState())){
				dao.insert(obj);
				idsNew.add(obj.getfID());
			}
			if(RowState.DELETE.equals(obj.getRowState())){
				dao.delete(obj.getfID());
				idsDel.add(obj.getfID());
			}
			if(RowState.EDIT.equals(obj.getRowState())){
				StorageItemBatch objNew = dao.update(obj);
				//返回+1后的version到前台BizData中进行刷新，使得前台的version与后台的一致。
				///////////////////////////////////////////////////////////////////////
				JSONObject jsonRow = new JSONObject();
				jsonRow.put("id", obj.getfID());
				jsonRow.put("version", objNew.getVersion());
				rows.add(jsonRow);
				//////////////////////////////////////////////////////////////////////
			}
		}
		
		data.put("rows", rows);
		data.put("idsNew", idsNew);
		data.put("idsDel", idsDel);
		
		return data;
	}
	

	
	/*
	//门店商品列表
	@Override
	public JSONObject queryJDBC_Store(JSONObject data) throws Throwable{
		return dao.queryJDBC_Store(data);
	}
	*/

	@Override
	public List<StorageItemBatch> queryList(JSONObject param) throws Throwable {
		// TODO Auto-generated method stub
		return dao.queryList(param);
	}

	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IStorageItemBatchService#getByNo(java.lang.String, java.lang.String, java.lang.String)
	 */
	@Override
	public StorageItemBatch getByNo(String storageID, String itemID, String batchNo, String enterpriseNo){
		return dao.getByNo(storageID, itemID, batchNo, enterpriseNo);
	}

	@Override
	public List<StorageItemBatch> getList(String storehouseID, String itemID, String enterpriseNo) {
		return dao.getList(storehouseID, itemID, enterpriseNo);
	}

	@Override
	public List<StorageItemBatch> getByStorageID(String storageID, String enterpriseNo) {
		return dao.getByStorageID(storageID, enterpriseNo);
	}

	
	@Override
	public List<StorageItemBatch> getByItemID(String itemID, String enterpriseNo) {
		return dao.getByItemID(itemID, enterpriseNo);
	}

	@Transactional
	@Override
	public StorageItemBatch storeRegister(
			String storageID
			, String storehouseID
//			, String storageNo
//			, String storageName
//			, String storageType
//			, String floorNo
			, String itemID
//			, String itemNo
//			, String itemDescribe
//			, String rationSize
//			, String unitCode
//			, String unitName
//			, String itemProperty
			, String batchNo
			, BigDecimal itemQuantity
//			, BigDecimal accountAmount
//			, BigDecimal materialAmount
//			, BigDecimal workingAmount
//			, BigDecimal manufactAmount
//			, BigDecimal processAmount
			, BigDecimal costingAmount

			, BigDecimal pieceQuantity
//			, String factoryNo
//			, String factoryName
			, String enterpriseNo
			, String enterpriseName
			, String userId
			) {
		
		StorageItemBatch si = dao.getByNo(storageID, itemID, batchNo, enterpriseNo);
		
		//首先判断是否存在记录，如果不存在就创建
		if (si==null) {
			//不存在，新建
			si = new StorageItemBatch();
			
			si.setfID(Utils.getUUID());
			si.setStorageID(storageID);
			si.setStorehouseID(storehouseID);
//			si.setStorageNo(storageNo);
//			si.setStorageName(storageName);
//			si.setFloorNo(floorNo);
			si.setItemID(itemID);
//			si.setItemNo(itemNo);
//			si.setItemDescribe(itemDescribe);
//			si.setRationSize(rationSize);
//			si.setUnitCode(unitCode);
//			si.setUnitName(unitName);
//			si.setItemProperty(itemProperty);
			si.setBatchNo(batchNo);
			si.setUserId(userId);
//			si.setFactoryNo(factoryNo);
//			si.setFactoryName(factoryName);
			si.setEnterpriseNo(enterpriseNo);
			si.setEnterpriseName(enterpriseName);

			si.setMinQuantity(new BigDecimal("0"));
			si.setMaxQuantity(new BigDecimal("0"));
			si.setItemQuantityL(new BigDecimal("0"));

			si.setPieceQuantityL(new BigDecimal("0"));
			
			si.setCostingAmount(new BigDecimal("0"));
			
			si.setStatus("open");
			
			dao.insert(si);
		}
		//登记
		
		si.setItemQuantityL(si.getItemQuantityL().add(itemQuantity));
		si.setPieceQuantityL(si.getPieceQuantityL().add(pieceQuantity));
		//金额
		si.setCostingAmount(si.getCostingAmount().add(costingAmount));
		
		si.setDateIn(Utils.getCurrentDate());
		
		try {
			dao.update(si);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return si;
	}


	//出库登记
	/* (non-Javadoc)
	 * @see com.iune.erp.inventory.IStorageItemBatchService#pickRegister(java.lang.String, java.lang.String, java.math.BigDecimal, java.math.BigDecimal, java.lang.String, java.lang.String)
	 */
	@Transactional
	@Override
	public StorageItemBatch pickRegister(
			String storageID
			, String storehouseID
//			, String storageNo
//			, String storageName
//			, String storageType
//			, String floorNo
			, String itemID
//			, String itemNo
//			, String itemDescribe
//			, String rationSize
//			, String unitCode
//			, String unitName
//			, String itemProperty
			, String batchNo
			, BigDecimal itemQuantity
//			, BigDecimal accountAmount
//			, BigDecimal materialAmount
//			, BigDecimal workingAmount
//			, BigDecimal manufactAmount
//			, BigDecimal processAmount
			, BigDecimal costingAmount

			, BigDecimal pieceQuantity
//			, String factoryNo
//			, String factoryName
			, String enterpriseNo
			, String enterpriseName
			, String userId
			) {
		
		StorageItemBatch si = dao.getByNo(storageID, itemID, batchNo, enterpriseNo);
		
		//首先判断是否存在记录，如果不存在就创建
		if (si==null) {
			//不存在，新建
			si = new StorageItemBatch();
			
			si.setfID(Utils.getUUID());
			si.setStorageID(storageID);
			si.setStorehouseID(storehouseID);
//			si.setStorageNo(storageNo);
//			si.setStorageName(storageName);
//			si.setFloorNo(floorNo);
			si.setItemID(itemID);
//			si.setItemNo(itemNo);
//			si.setItemDescribe(itemDescribe);
//			si.setRationSize(rationSize);
//			si.setUnitCode(unitCode);
//			si.setUnitName(unitName);
//			si.setItemProperty(itemProperty);
			si.setBatchNo(batchNo);
			si.setUserId(userId);
//			si.setFactoryNo(factoryNo);
//			si.setFactoryName(factoryName);
			si.setEnterpriseNo(enterpriseNo);
			si.setEnterpriseName(enterpriseName);

			si.setMinQuantity(new BigDecimal("0"));
			si.setMaxQuantity(new BigDecimal("0"));
			si.setItemQuantityL(new BigDecimal("0"));

			si.setPieceQuantityL(new BigDecimal("0"));
			
			si.setCostingAmount(new BigDecimal("0"));

			si.setStatus("open");

			dao.insert(si);
		}
		//登记
		
		si.setItemQuantityL(si.getItemQuantityL().subtract(itemQuantity));
		si.setPieceQuantityL(si.getPieceQuantityL().subtract(pieceQuantity));
		//金额
		si.setCostingAmount(si.getCostingAmount().subtract(costingAmount));
		
		si.setDateOut(Utils.getCurrentDate());

		try {
			dao.update(si);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return si;
	}

	@Override
	public StorageItemBatch packing(
			String userId 
			,String enterpriseNo 
			,String enterpriseName 
			){
		
		StorageItemBatch obj = new StorageItemBatch();
		String fID = Utils.getUUID();
		obj.setfID(fID);
		
		obj.setStatus("open");
		
		obj.setMinQuantity(BigDecimal.ZERO);
		obj.setMaxQuantity(BigDecimal.ZERO);
		obj.setItemQuantityL(BigDecimal.ZERO);
		obj.setPieceQuantityL(BigDecimal.ZERO);
		
		obj.setCreateDatetime(Utils.getCurrentDateTime());
		
		obj.setUserId(userId);
		obj.setEnterpriseNo(enterpriseNo);
		obj.setEnterpriseName(enterpriseName);
		
		obj.setVersion(0);
		
		return obj;
	}

	//库存金额（不再使用）
	@Override
	public BigDecimal getCostingAmount(String enterpriseNo) throws Throwable {
		List<Object> params = new ArrayList<Object>();
		params.add(enterpriseNo);

		return dao.getCostingAmount(params);
	}

	//库存数量（不再使用）
	@Override
	public BigDecimal getQuantityL(String enterpriseNo) throws Throwable {
		List<Object> params = new ArrayList<Object>();
		params.add(enterpriseNo);

		return dao.getQuantityL(params);
	}
	
	@Override
	public JSONObject newData(JSONObject data) {
		return dao.create(data);
	}
	
	@Override
	public JSONObject deleteData(JSONObject param) {
		//System.out.println("fileFactoryCreate.param-->>"+param.toJSONString());
		JSONArray ids = param.getJSONArray("ids");
		for(int i=0;i<ids.size();i++){
			String id = ids.getString(i);
			//这里可以增加是否可删除的判断
			
			dao.delete(id);
		}

		JSONObject data = new JSONObject();
		data.put("ids", ids);
		
		JSONObject json = new JSONObject();
		json.put("code", 0);
		json.put("msg", "success");
		json.put("data", data);
		
		return json;
	}

	/*
	在@Transaction注解中定义noRollbackFor和RollbackFor指定某种异常是否回滚。 
	@Transactional(noRollbackFor=RuntimeException.class) 
	@Transactional(RollbackFor=Exception.class) 
	*/
	@Transactional
	@Override
	public JSONObject saveData(JSONObject param) {
		//Spring的事务管理默认只对出现运行期异常(java.lang.RuntimeException及其子类)进行回滚。 
		//如果一个方法抛出Exception或者Checked异常，Spring事务管理默认不进行回滚。 
		// JSON转换Table
		//System.out.println(object);
		JSONObject data;
		try {
			data = this.save(param);
					
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", data);
			
			return json;
			
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			
			return json;
		} 
	}
	
	/* (non-Javadoc)
	 * @see com.iune.erp.baseinfo.aaa#queryJDBC(com.alibaba.fastjson.JSONObject)
	 */
	@Transactional(propagation=Propagation.NOT_SUPPORTED,readOnly=true)
	@Override
	public JSONObject queryData(JSONObject param){
		//在此层面（ServiceImpl）统一处理异常，此层面直接被controller调用，面对BizData
		
		try {
			JSONObject jsonTable = dao.query(param);
			
			JSONObject json = new JSONObject();
			json.put("code", 0);
			json.put("msg", "success");
			json.put("data", jsonTable);
			
			return json;
		} catch (SQLException e) {
			e.printStackTrace();
			
			JSONObject json = new JSONObject();
			json.put("code", -1);
			json.put("msg", e.getMessage());
			return json;
		}
	}

	@Override
	public JSONObject validData(JSONObject param) {
		// TODO Auto-generated method stub
		return null;
	}

}
